/**
 * Copyright 2004 - 2007 Blue Bamboo International Inc. 
 *           All rights reserved.
 *
 *
 * Blue Bamboo PROPRIETARY/CONFIDENTIAL.
 *
 */

package com.bluebamboo.bluetools.pingpang.connection;

import gnu.io.SerialPort;

import org.apache.mina.transport.serial.SerialAddress;
import org.apache.mina.transport.serial.SerialConnector;
import org.apache.mina.transport.serial.SerialAddress.DataBits;
import org.apache.mina.transport.serial.SerialAddress.FlowControl;
import org.apache.mina.transport.serial.SerialAddress.Parity;
import org.apache.mina.transport.serial.SerialAddress.StopBits;

import com.bluebamboo.bluetools.pingpang.bean.SerialBean;

/**
 * DOCME
 * 
 * @author tanxuqing
 * @date Sep 13, 2009
 * @since
 */
public class SerialConnectionHandler extends AbstractConnectionHandler<SerialBean> {

	private SerialConnector connector;

	/**
	 * @param connectonBean
	 */
	public SerialConnectionHandler(SerialBean connectonBean) {
		super(connectonBean);
	}

	public void connect() throws Exception {
		super.connect();
		connector = new SerialConnector();
		SerialBean serialBean = getConnectionBean();
		connector.setHandler(getIoHandler());
		DataBits dataBits = getDataBits(serialBean.getDataBits());
		StopBits stopBits = getStopBits(serialBean.getStopBits());
		Parity parity = getParity(serialBean.getParity());
		FlowControl flowControl = getFlowControl(serialBean.getFlowControlMode());
		SerialAddress portAddress = new SerialAddress(serialBean.getPort(), serialBean.getBaudRate(), dataBits,
				stopBits, parity, flowControl);
		connector.connect(portAddress);
	}

	public void disconnect() throws Exception {
		super.disconnect();
		connector.dispose();
	}

	private static DataBits getDataBits(int dataBits) {
		switch (dataBits) {
		case SerialPort.DATABITS_5:
			return DataBits.DATABITS_5;
		case SerialPort.DATABITS_6:
			return DataBits.DATABITS_6;
		case SerialPort.DATABITS_7:
			return DataBits.DATABITS_7;
		case SerialPort.DATABITS_8:
			return DataBits.DATABITS_8;
		default:
			throw new RuntimeException("unsupported dataBits: " + dataBits);
		}
	}

	private static Parity getParity(int parity) {
		switch (parity) {
		case SerialPort.PARITY_NONE:
			return Parity.NONE;
		case SerialPort.PARITY_EVEN:
			return Parity.EVEN;
		case SerialPort.PARITY_MARK:
			return Parity.MARK;
		case SerialPort.PARITY_ODD:
			return Parity.ODD;
		case SerialPort.PARITY_SPACE:
			return Parity.SPACE;
		default:
			throw new RuntimeException("unsupported parity: " + parity);
		}
	}

	private static StopBits getStopBits(int stopBits) {
		switch (stopBits) {
		case SerialPort.STOPBITS_1:
			return StopBits.BITS_1;
		case SerialPort.STOPBITS_1_5:
			return StopBits.BITS_1_5;
		case SerialPort.STOPBITS_2:
			return StopBits.BITS_2;
		default:
			throw new RuntimeException("unsupported stopBits: " + stopBits);
		}
	}

	private static FlowControl getFlowControl(int flowControl) {
		switch (flowControl) {
		case SerialPort.FLOWCONTROL_NONE:
			return FlowControl.NONE;
		case SerialPort.FLOWCONTROL_RTSCTS_IN:
			return FlowControl.RTSCTS_IN;
		case SerialPort.FLOWCONTROL_RTSCTS_OUT:
			return FlowControl.RTSCTS_OUT;
		case SerialPort.FLOWCONTROL_XONXOFF_IN:
			return FlowControl.XONXOFF_IN;
		case SerialPort.FLOWCONTROL_XONXOFF_OUT:
			return FlowControl.XONXOFF_OUT;
		default:
			throw new RuntimeException("unsupported flowcontrol: " + flowControl);
		}
	}
}
